﻿using System;
using Avalonia;
using Avalonia.Input;
using Avalonia.OpenGL;
using Avalonia.OpenGL.Controls;
using Avalonia.Rendering;
using Kitware.mummy.Runtime;
using Kitware.VTK;

namespace Kitware.AvaloniaControls
{
    public class RenderWindowControl : OpenGlControlBase, ICustomHitTest
    {
        bool ICustomHitTest.HitTest(Point point)
        {
            return true;
        }

        public RenderWindowControl()
        {
            //Methods.GetTypeEntryCount();
            base.Focusable = true;
            this.RenderWindow = vtkGenericOpenGLRenderWindow.New();
            this.RenderWindow.SetFrameBlitModeToBlitToCurrent();
            this.RenderWindow.WindowMakeCurrentEvt += new vtkObject.vtkObjectEventHandler(this.WindowMakeCurrentEvent);
            this.RenderWindow.WindowFrameEvt += new vtkObject.vtkObjectEventHandler(this.WindowFrameEvent);
            this.Interactor = vtkGenericRenderWindowInteractor.New();
            this.RenderWindow.SetInteractor(this.Interactor);
            this.Interactor.EnableRenderOff();
            this.Interactor.RenderEvt += new vtkObject.vtkObjectEventHandler(this.Interactor_RenderEvt);
            this.Interactor.CreateTimerEvt += new vtkObject.vtkObjectEventHandler(this.Interactor_CreateTimerEvt);
            this.Interactor.DestroyTimerEvt += new vtkObject.vtkObjectEventHandler(this.Interactor_DestroyTimerEvt);
            //vtkRenderWindow vtkRenderWindow = vtkRenderWindow.New();
            //vtkRenderWindow.OffScreenRenderingOn();
            //this.TimerInteractor = vtkRenderWindowInteractor.New();
            //this.TimerInteractor.SetRenderWindow(vtkRenderWindow);
            //this.TimerInteractor.EnableRenderOff();
            //this.TimerInteractor.Initialize();
            //vtkRenderWindow.Dispose();
            //this.TimerInteractor.TimerEvt += new vtkObject.vtkObjectEventHandler(this.InternalTimerEvent);
        }

        private void Interactor_RenderEvt(vtkObject sender, vtkObjectEventArgs e)
        {
            base.RequestNextFrameRendering();
        }

        private void WindowFrameEvent(vtkObject sender, vtkObjectEventArgs e)
        {
        }

        private void WindowMakeCurrentEvent(vtkObject sender, vtkObjectEventArgs e)
        {
            if (this.RenderWindow.IsCurrent())
            {
                return;
            }
            this.RenderWindow.SetIsCurrent(true);
        }

        protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
        {
            if (base.VisualRoot != null && change.Property == Visual.BoundsProperty)
            {
                double renderScaling = base.VisualRoot.RenderScaling;
                int num = Math.Max(1, (int)(base.Bounds.Width * renderScaling));
                int num2 = Math.Max(1, (int)(base.Bounds.Height * renderScaling));
                this.RenderWindow.SetSize(num, num2);
                this.RenderWindow.GetInteractor().SetSize(num, num2);
            }
            base.OnPropertyChanged(change);
        }

        protected override void OnOpenGlInit(GlInterface gl)
        {
            this.RenderWindow.InitializeFromCurrentContext();
        }

        protected override void OnOpenGlDeinit(GlInterface gl)
        {
            this.RenderWindow.ReleaseGraphicsResources(null);
        }

        protected override void OnOpenGlRender(GlInterface gl, int fb)
        {
            this.RenderWindow.Render();
        }

        protected override void OnPointerMoved(PointerEventArgs e)
        {
            Point point = ((base.VisualRoot != null) ? base.VisualRoot.RenderScaling : 1.0) * e.GetPosition(this);
            this.RenderWindow.GetInteractor().SetEventPositionFlipY((int)point.X, (int)point.Y);
            this.RenderWindow.GetInteractor().MouseMoveEvent();
        }

        protected override void OnPointerPressed(PointerPressedEventArgs e)
        {
            if (!base.IsFocused)
            {
                base.Focus(0, 0);
            }
            Point point = ((base.VisualRoot != null) ? base.VisualRoot.RenderScaling : 1.0) * e.GetPosition(this);
            this.RenderWindow.GetInteractor().SetEventPositionFlipY((int)point.X, (int)point.Y);
            if (e.GetCurrentPoint(this).Properties.PointerUpdateKind == PointerUpdateKind.LeftButtonPressed)
            {
                this.RenderWindow.GetInteractor().LeftButtonPressEvent();
            }
            if (e.GetCurrentPoint(this).Properties.PointerUpdateKind == PointerUpdateKind.RightButtonPressed)
            {
                this.RenderWindow.GetInteractor().RightButtonPressEvent();
            }
            if (e.GetCurrentPoint(this).Properties.PointerUpdateKind == PointerUpdateKind.MiddleButtonPressed)
            {
                this.RenderWindow.GetInteractor().MiddleButtonPressEvent();
            }
        }

        protected override void OnPointerReleased(PointerReleasedEventArgs e)
        {
            Point point = ((base.VisualRoot != null) ? base.VisualRoot.RenderScaling : 1.0) * e.GetPosition(this);
            this.RenderWindow.GetInteractor().SetEventPositionFlipY((int)point.X, (int)point.Y);
            if (e.GetCurrentPoint(this).Properties.PointerUpdateKind == PointerUpdateKind.LeftButtonReleased)
            {
                this.RenderWindow.GetInteractor().LeftButtonReleaseEvent();
            }
            if (e.GetCurrentPoint(this).Properties.PointerUpdateKind == PointerUpdateKind.RightButtonReleased)
            {
                this.RenderWindow.GetInteractor().RightButtonReleaseEvent();
            }
            if (e.GetCurrentPoint(this).Properties.PointerUpdateKind == PointerUpdateKind.MiddleButtonReleased)
            {
                this.RenderWindow.GetInteractor().MiddleButtonReleaseEvent();
            }
        }

        protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
        {
            if (!base.IsFocused)
            {
                base.Focus(0, 0);
            }
            if (e.Delta.Y < 0.0)
            {
                this.RenderWindow.GetInteractor().MouseWheelBackwardEvent();
                return;
            }
            if (e.Delta.Y > 0.0)
            {
                this.RenderWindow.GetInteractor().MouseWheelForwardEvent();
            }
        }

        protected void SetInteractorKeyEventInformation(KeyEventArgs e)
        {
            int num = e.KeyModifiers.HasFlag(KeyModifiers.Control) ? 1 : 0;
            int num2 = e.KeyModifiers.HasFlag(KeyModifiers.Shift) ? 1 : 0;
            int altKey = e.KeyModifiers.HasFlag(KeyModifiers.Alt) ? 1 : 0;
            string text = e.Key.ToString();
            sbyte b = (sbyte)text[0];
            this.RenderWindow.GetInteractor().SetKeyEventInformation(num, num2, b, 0, text);
            this.RenderWindow.GetInteractor().SetAltKey(altKey);
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            this.SetInteractorKeyEventInformation(e);
            this.RenderWindow.GetInteractor().KeyPressEvent();
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            this.SetInteractorKeyEventInformation(e);
            this.RenderWindow.GetInteractor().KeyReleaseEvent();
        }

        private void Interactor_CreateTimerEvt(vtkObject sender, vtkObjectEventArgs e)
        {
            if (this.Interactor.GetTimerEventType() == 1)
            {
                this.TimerInteractor.CreateOneShotTimer(this.Interactor.GetTimerDuration());
                return;
            }
            if (this.Interactor.GetTimerEventType() == 2)
            {
                this.TimerInteractor.CreateRepeatingTimer(this.Interactor.GetTimerDuration());
            }
        }

        private void Interactor_DestroyTimerEvt(vtkObject sender, vtkObjectEventArgs e)
        {
            this.TimerInteractor.DestroyTimer(this.Interactor.GetTimerEventId());
        }

        private void InternalTimerEvent(vtkObject sender, vtkObjectEventArgs e)
        {
            this.Interactor.TimerEvent();
        }

        public vtkRenderWindowInteractor TimerInteractor;

        public vtkGenericOpenGLRenderWindow RenderWindow;

        private vtkGenericRenderWindowInteractor Interactor;
    }
}
